<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>在浏览器输入 URL 回车之后发生了什么（超详细版） | Leonの博客</title><meta name="keywords" content="http网络"><meta name="author" content="Leon"><meta name="copyright" content="Leon"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta http-equiv="Cache-Control" content="no-transform"><meta http-equiv="Cache-Control" content="no-siteapp"><meta name="description" content="在浏览器输入 URL 回车之后发生了什么">
<meta property="og:type" content="article">
<meta property="og:title" content="在浏览器输入 URL 回车之后发生了什么（超详细版）">
<meta property="og:url" content="https://gitee.com/Rickest_Rick/rickest_rick.git/2020/10/07/URL/index.html">
<meta property="og:site_name" content="Leonの博客">
<meta property="og:description" content="在浏览器输入 URL 回车之后发生了什么">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://pic.downk.cc/item/5ff721fa3ffa7d37b379bbff.jpg">
<meta property="article:published_time" content="2020-10-07T09:08:34.000Z">
<meta property="article:modified_time" content="2021-01-07T14:59:20.063Z">
<meta property="article:author" content="Leon">
<meta property="article:tag" content="http网络">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://pic.downk.cc/item/5ff721fa3ffa7d37b379bbff.jpg"><link rel="shortcut icon" href="/rickest_rick/img/favicon.png"><link rel="canonical" href="https://gitee.com/Rickest_Rick/rickest_rick.git/2020/10/07/URL/"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="preconnect" href="//busuanzi.ibruce.info"/><link rel="stylesheet" href="/rickest_rick/css/index.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free/css/all.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.css"><script>var GLOBAL_CONFIG = { 
  root: '/rickest_rick/',
  hexoversion: '5.1.1',
  algolia: undefined,
  localSearch: {"path":"search.xml","languages":{"hits_empty":"找不到您查询的内容：${query}"}},
  translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"簡"},
  noticeOutdate: undefined,
  highlight: {"plugin":"highlighjs","highlightCopy":true,"highlightLang":true},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  relativeDate: {
    homepage: false,
    post: false
  },
  runtime: '天',
  date_suffix: {
    just: '刚刚',
    min: '分钟前',
    hour: '小时前',
    day: '天前',
    month: '个月前'
  },
  copyright: undefined,
  ClickShowText: undefined,
  lightbox: 'fancybox',
  Snackbar: {"chs_to_cht":"你已切换为繁体","cht_to_chs":"你已切换为简体","day_to_night":"你已切换为深色模式","night_to_day":"你已切换为浅色模式","bgLight":"#49b1f5","bgDark":"#121212","position":"bottom-left"},
  justifiedGallery: {
    js: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/js/jquery.justifiedGallery.min.js',
    css: 'https://cdn.jsdelivr.net/npm/justifiedGallery/dist/css/justifiedGallery.min.css'
  },
  isPhotoFigcaption: true,
  islazyload: false,
  isanchor: false
};

var saveToLocal = {
  set: function setWithExpiry(key, value, ttl) {
    const now = new Date()
    const expiryDay = ttl * 86400000
    const item = {
      value: value,
      expiry: now.getTime() + expiryDay,
    }
    localStorage.setItem(key, JSON.stringify(item))
  },

  get: function getWithExpiry(key) {
    const itemStr = localStorage.getItem(key)

    if (!itemStr) {
      return undefined
    }
    const item = JSON.parse(itemStr)
    const now = new Date()

    if (now.getTime() > item.expiry) {
      localStorage.removeItem(key)
      return undefined
    }
    return item.value
  }
}</script><script id="config_change">var GLOBAL_CONFIG_SITE = { 
  isPost: true,
  isHome: false,
  isHighlightShrink: false,
  isSidebar: true,
  postUpdate: '2021-01-07 22:59:20'
}</script><noscript><style type="text/css">
  #nav {
    opacity: 1
  }
  .justified-gallery img {
    opacity: 1
  }

  #recent-posts time,
  #post-meta time {
    display: inline !important
  }
</style></noscript><script>(function () {
  window.activateDarkMode = function () {
    document.documentElement.setAttribute('data-theme', 'dark')
    if (document.querySelector('meta[name="theme-color"]') !== null) {
      document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
    }
  }
  window.activateLightMode = function () {
    document.documentElement.setAttribute('data-theme', 'light')
    if (document.querySelector('meta[name="theme-color"]') !== null) {
      document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
    }
  }

  const autoChangeMode = 'false'
  const t = saveToLocal.get('theme')
  if (autoChangeMode === '1') {
    const isDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
    const isLightMode = window.matchMedia('(prefers-color-scheme: light)').matches
    const isNotSpecified = window.matchMedia('(prefers-color-scheme: no-preference)').matches
    const hasNoSupport = !isDarkMode && !isLightMode && !isNotSpecified

    if (t === undefined) {
      if (isLightMode) activateLightMode()
      else if (isDarkMode) activateDarkMode()
      else if (isNotSpecified || hasNoSupport) {
        const now = new Date()
        const hour = now.getHours()
        const isNight = hour <= 6 || hour >= 18
        isNight ? activateDarkMode() : activateLightMode()
      }
      window.matchMedia('(prefers-color-scheme: dark)').addListener(function (e) {
        if (saveToLocal.get('theme') === undefined) {
          e.matches ? activateDarkMode() : activateLightMode()
        }
      })
    } else if (t === 'light') activateLightMode()
    else activateDarkMode()
  } else if (autoChangeMode === '2') {
    const now = new Date()
    const hour = now.getHours()
    const isNight = hour <= 6 || hour >= 18
    if (t === undefined) isNight ? activateDarkMode() : activateLightMode()
    else if (t === 'light') activateLightMode()
    else activateDarkMode()
  } else {
    if (t === 'dark') activateDarkMode()
    else if (t === 'light') activateLightMode()
  }
})()</script><style type="text/css">#toggle-sidebar {bottom: 80px}</style><div class="aplayer" data-id="2693598459" data-server="netease" data-type="playlist" data-fixed="true" data-listFolded="false" data-order="random" data-preload="none"></div><link rel="stylesheet" href="https://cdn.bootcss.com/aplayer/1.10.1/APlayer.min.css"><script src="https://cdn.bootcss.com/aplayer/1.10.1/APlayer.min.js"></script><script src="https://cdn.jsdelivr.net/npm/meting@1.2.0/dist/Meting.min.js"></script><meta name="generator" content="Hexo 5.1.1"></head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">加载中...</div></div></div><div id="mobile-sidebar"><div id="menu_mask"></div><div id="mobile-sidebar-menus"><div class="mobile_author_icon"><img class="avatar-img" src="https://p.pstatp.com/origin/1393c0000008cd9a00a6f" onerror="onerror=null;src='/img/friend_404.gif'" alt="avatar"/></div><div class="mobile_post_data"><div class="mobile_data_item is-center"><div class="mobile_data_link"><a href="/rickest_rick/archives/"><div class="headline">文章</div><div class="length_num">3</div></a></div></div><div class="mobile_data_item is-center">      <div class="mobile_data_link"><a href="/rickest_rick/tags/"><div class="headline">标签</div><div class="length_num">3</div></a></div></div><div class="mobile_data_item is-center">     <div class="mobile_data_link"><a href="/rickest_rick/categories/"><div class="headline">分类</div><div class="length_num">2</div></a></div></div></div><hr/><div class="menus_items"><div class="menus_item"><a class="site-page" href="/rickest_rick/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/rickest_rick/archives/"><i class="fa-fw fas fa-archive"></i><span> 事件轴</span></a></div><div class="menus_item"><a class="site-page" href="/rickest_rick/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/rickest_rick/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> List</span><i class="fas fa-chevron-down expand"></i></a><ul class="menus_item_child"><li><a class="site-page" href="/rickest_rick/music/"><i class="fa-fw fas fa-music"></i><span> Music</span></a></li><li><a class="site-page" href="/rickest_rick/bangumis/"><i class="fa-fw fas fa-video"></i><span> 追番列表</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/rickest_rick/link/"><i class="fa-fw fas fa-link"></i><span> 友情链接</span></a></div><div class="menus_item"><a class="site-page" href="/rickest_rick/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div id="body-wrap"><div id="sidebar"><i class="fas fa-arrow-right on" id="toggle-sidebar"></i><div class="sidebar-toc"><div class="sidebar-toc__title">目录</div><div class="sidebar-toc__progress"><span class="progress-notice">你已经读了</span><span class="progress-num">0</span><span class="progress-percentage">%</span><div class="sidebar-toc__progress-bar">     </div></div><div class="sidebar-toc__content"><ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%89%8D%E8%A8%80"><span class="toc-number">1.</span> <span class="toc-text">前言</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%A4%A7%E8%87%B4%E6%B5%81%E7%A8%8B"><span class="toc-number">2.</span> <span class="toc-text">大致流程</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#URL%E8%A7%A3%E6%9E%90"><span class="toc-number">2.1.</span> <span class="toc-text">URL解析</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#DNS-%E6%9F%A5%E8%AF%A2"><span class="toc-number">2.2.</span> <span class="toc-text">DNS 查询</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#TCP%E9%93%BE%E6%8E%A5"><span class="toc-number">2.3.</span> <span class="toc-text">TCP链接</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#1-%E5%BA%94%E7%94%A8%E5%B1%82%EF%BC%9A%E5%8F%91%E9%80%81-HTTP-%E8%AF%B7%E6%B1%82"><span class="toc-number">2.3.1.</span> <span class="toc-text">1.应用层：发送 HTTP 请求</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#2-%E4%BC%A0%E8%BE%93%E5%B1%82%EF%BC%9ATCP-%E4%BC%A0%E8%BE%93%E6%8A%A5%E6%96%87"><span class="toc-number">2.3.2.</span> <span class="toc-text">2. 传输层：TCP 传输报文</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#3-%E7%BD%91%E7%BB%9C%E5%B1%82%EF%BC%9AIP-%E5%8D%8F%E8%AE%AE%E6%9F%A5%E8%AF%A2-Mac-%E5%9C%B0%E5%9D%80"><span class="toc-number">2.3.3.</span> <span class="toc-text">3. 网络层：IP 协议查询 Mac 地址</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#4-%E9%93%BE%E8%B7%AF%E5%B1%82%EF%BC%9A%E4%BB%A5%E5%A4%AA%E7%BD%91%E5%8D%8F%E8%AE%AE"><span class="toc-number">2.3.4.</span> <span class="toc-text">4. 链路层：以太网协议</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%A4%84%E7%90%86%E8%AF%B7%E6%B1%82"><span class="toc-number">2.4.</span> <span class="toc-text">服务器处理请求</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%B5%8F%E8%A7%88%E5%99%A8%E6%8E%A5%E5%8F%97%E5%93%8D%E5%BA%94"><span class="toc-number">2.5.</span> <span class="toc-text">浏览器接受响应</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%B8%B2%E6%9F%93%E9%A1%B5%E9%9D%A2"><span class="toc-number">2.6.</span> <span class="toc-text">渲染页面</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#HTML-%E8%A7%A3%E6%9E%90"><span class="toc-number">2.6.1.</span> <span class="toc-text">HTML 解析</span></a><ol class="toc-child"><li class="toc-item toc-level-5"><a class="toc-link" href="#%E4%BD%88%E5%B1%80%E4%B8%8E%E7%BB%98%E8%A3%BD"><span class="toc-number">2.6.1.1.</span> <span class="toc-text">佈局与绘製</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E5%90%88%E4%BD%B5%E6%B8%B2%E6%9F%93%E5%B1%82"><span class="toc-number">2.6.1.2.</span> <span class="toc-text">合併渲染层</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#%E8%BF%B4%E6%B5%81%E4%B8%8E%E9%87%8D%E7%BB%98"><span class="toc-number">2.6.1.3.</span> <span class="toc-text">迴流与重绘</span></a></li><li class="toc-item toc-level-5"><a class="toc-link" href="#JavaScript-%E7%BC%96%E8%AF%91%E6%89%A7%E8%A1%8C"><span class="toc-number">2.6.1.4.</span> <span class="toc-text">JavaScript 编译执行</span></a><ol class="toc-child"><li class="toc-item toc-level-6"><a class="toc-link" href="#%E8%AF%8D%E6%B3%95%E5%88%86%E6%9E%90"><span class="toc-number">2.6.1.4.1.</span> <span class="toc-text">词法分析</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#%E9%A2%84%E7%BC%96%E8%AF%91"><span class="toc-number">2.6.1.4.2.</span> <span class="toc-text">预编译</span></a></li><li class="toc-item toc-level-6"><a class="toc-link" href="#%E6%89%A7%E8%A1%8C"><span class="toc-number">2.6.1.4.3.</span> <span class="toc-text">执行</span></a></li></ol></li></ol></li></ol></li></ol></li></ol></div></div></div><header class="post-bg" id="page-header" style="background-image: url(https://pic.downk.cc/item/5ff721fa3ffa7d37b379bbff.jpg)"><nav id="nav"><span id="blog_name"><a id="site-name" href="/rickest_rick/">Leonの博客</a></span><span id="menus"><div id="search_button"><a class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/rickest_rick/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><a class="site-page" href="/rickest_rick/archives/"><i class="fa-fw fas fa-archive"></i><span> 事件轴</span></a></div><div class="menus_item"><a class="site-page" href="/rickest_rick/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></div><div class="menus_item"><a class="site-page" href="/rickest_rick/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></div><div class="menus_item"><a class="site-page" href="javascript:void(0);"><i class="fa-fw fas fa-list"></i><span> List</span><i class="fas fa-chevron-down expand"></i></a><ul class="menus_item_child"><li><a class="site-page" href="/rickest_rick/music/"><i class="fa-fw fas fa-music"></i><span> Music</span></a></li><li><a class="site-page" href="/rickest_rick/bangumis/"><i class="fa-fw fas fa-video"></i><span> 追番列表</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/rickest_rick/link/"><i class="fa-fw fas fa-link"></i><span> 友情链接</span></a></div><div class="menus_item"><a class="site-page" href="/rickest_rick/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><span class="close" id="toggle-menu"><a class="site-page"><i class="fas fa-bars fa-fw"></i></a></span></span></nav><div id="post-info"><div id="post-title"><div class="posttitle">在浏览器输入 URL 回车之后发生了什么（超详细版）</div></div><div id="post-meta"><div class="meta-firstline"><span class="post-meta-date"><i class="far fa-calendar-alt fa-fw post-meta-icon"></i><span class="post-meta-label">发表于</span><time class="post-meta-date-created" datetime="2020-10-07T09:08:34.000Z" title="发表于 2020-10-07 17:08:34">2020-10-07</time><span class="post-meta-separator">|</span><i class="fas fa-history fa-fw post-meta-icon"></i><span class="post-meta-label">更新于</span><time class="post-meta-date-updated" datetime="2021-01-07T14:59:20.063Z" title="更新于 2021-01-07 22:59:20">2021-01-07</time></span><span class="post-meta-categories"><span class="post-meta-separator">|</span><i class="fas fa-inbox fa-fw post-meta-icon"></i><a class="post-meta-categories" href="/rickest_rick/categories/Web/">Web</a></span></div><div class="meta-secondline"> <span class="post-meta-separator">|</span><span class="post-meta-wordcount"><i class="far fa-file-word fa-fw post-meta-icon"></i><span class="post-meta-label">字数总计:</span><span class="word-count">3.9k</span><span class="post-meta-separator">|</span><i class="far fa-clock fa-fw post-meta-icon"></i><span class="post-meta-label">阅读时长:</span><span>12分钟</span></span><span class="post-meta-separator">|</span><span class="post-meta-pv-cv"><i class="far fa-eye fa-fw post-meta-icon"></i><span class="post-meta-label">阅读量:</span><span id="busuanzi_value_page_pv"></span></span></div></div></div></header><main class="layout_post" id="content-inner"><article id="post"><div class="post-content" id="article-container"><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>这个问题已经是老生常谈了，更是经常被作为面试的压轴题出现，网上也有很多文章，但最近閒的无聊，然后就自己做了一篇笔记，感觉比之前理解更透彻了。</p>
<h2 id="大致流程"><a href="#大致流程" class="headerlink" title="大致流程"></a>大致流程</h2><p>1.URL 解析</p>
<p>2.DNS 查询</p>
<p>3.TCP 连接</p>
<p>4.处理请求</p>
<p>5.接受响应</p>
<p>6.渲染页面</p>
<h3 id="URL解析"><a href="#URL解析" class="headerlink" title="URL解析"></a>URL解析</h3><p><strong>地址解析:</strong></p>
<p>首先判断你输入的是一个合法的 URL 还是一个待搜索的关键词，并且根据你输入的内容进行自动完成、字符编码等操作。</p>
<p><strong>HSTS:</strong></p>
<p>由于安全隐患，会使用 HSTS 强制客户端使用 HTTPS 访问页面。详见：</p>
<p><strong>其他操作:</strong></p>
<p>浏览器还会进行一些额外的操作，比如安全检查、访问限制（之前国产浏览器限制 996.icu）。</p>
<p><strong>检查缓存:</strong></p>
<p><img src="https://i.loli.net/2020/10/07/McX9avN6j43wLok.png" alt="What_happens_when_you_type_an_URL_in_the_browser_and_press_enter.png"></p>
<h3 id="DNS-查询"><a href="#DNS-查询" class="headerlink" title="DNS 查询"></a>DNS 查询</h3><p><strong>基本步骤</strong></p>
<p><img src="https://i.loli.net/2020/10/07/njX54CcUJSYf31B.png" alt="What_happens_when_you_type_an_URL_in_the_browser_and_press_enter_baisc_process.png"></p>
<p><strong>浏览器缓存</strong><br>浏览器会先检查是否在缓存中，没有则调用系统库函数进行查询。</p>
<p><strong>操作系统缓存</strong><br>操作系统也有自己的 DNS 缓存，但在这之前，会向检查域名是否存在本地的 Hosts 文件里，没有则向 DNS 服务器发送查询请求。</p>
<p><strong>路由器缓存</strong><br>路由器也有自己的缓存。</p>
<p><strong>ISP DNS 缓存</strong><br>ISP DNS 就是在客户端电脑上设置的首选 DNS 服务器，它们在大多数情况下都会有缓存。</p>
<p><strong>根域名服务器查询</strong><br>在前面所有步骤没有缓存的情况下，本地 DNS 服务器会将请求转发到互联网上的根域，下面这个图很好的诠释了整个流程：</p>
<p><img src="https://i.loli.net/2020/10/07/q8gfu5NJBtiheV7.png" alt="What_happens_when_you_type_an_URL_in_the_browser_and_press_enter_dns.png"></p>
<p><strong>需要注意的点</strong></p>
<ol>
<li>递归方式：一路查下去中间不返回，得到最终结果才返回信息（浏览器到本地 DNS 服务器的过程）</li>
<li>迭代方式，就是本地 DNS 服务器到根域名服务器查询的方式。</li>
<li>什么是 DNS 劫持</li>
<li>前端 dns-prefetch 优化</li>
</ol>
<h3 id="TCP链接"><a href="#TCP链接" class="headerlink" title="TCP链接"></a>TCP链接</h3><p>TCP/IP 分为四层，在发送数据时，每层都要对数据进行封装：</p>
<p><img src="https://i.loli.net/2020/10/07/7sYlmdvQR9Ne8bH.png" alt="What_happens_when_you_type_an_URL_in_the_browser_and_press_enter_tcp.png"></p>
<h4 id="1-应用层：发送-HTTP-请求"><a href="#1-应用层：发送-HTTP-请求" class="headerlink" title="1.应用层：发送 HTTP 请求"></a>1.应用层：发送 HTTP 请求</h4><p>在前面的步骤我们已经得到服务器的 IP 地址，浏览器会开始构造一个 HTTP 报文，其中包括：</p>
<ul>
<li>请求报头（Request Header）：请求方法、目标地址、遵循的协议等等</li>
<li>请求主体（其他参数）</li>
</ul>
<p>其中需要注意的点：</p>
<ul>
<li>浏览器只能发送 GET、POST 方法，而打开网页使用的是 GET 方法</li>
</ul>
<h4 id="2-传输层：TCP-传输报文"><a href="#2-传输层：TCP-传输报文" class="headerlink" title="2. 传输层：TCP 传输报文"></a>2. 传输层：TCP 传输报文</h4><p>传输层会发起一条到达服务器的 TCP 连接，为了方便传输，会对数据进行分割（以报文段为单位），并标记编号，方便服务器接受时能够準确地还原报文信息。</p>
<p>在建立连接前，会先进行 TCP 三次握手。</p>
<blockquote>
<p>关于 TCP/IP 三次握手，网上已经有很多段子和图片生动地描述了。<br>相关知识点：</p>
<p>1.SYN 泛洪攻击</p>
</blockquote>
<h4 id="3-网络层：IP-协议查询-Mac-地址"><a href="#3-网络层：IP-协议查询-Mac-地址" class="headerlink" title="3. 网络层：IP 协议查询 Mac 地址"></a>3. 网络层：IP 协议查询 Mac 地址</h4><p>将数据段打包，并加入源及目标的 IP 地址，并且负责寻找传输路线。</p>
<p>判断目标地址是否与当前地址处于同一网络中，是的话直接根据 Mac 地址发送，否则使用路由表查找下一跳地址，以及使用 ARP 协议查询它的 Mac 地址。</p>
<blockquote>
<p>注意：在 OSI 参考模型中 ARP 协议位于链路层，但在 TCP/IP 中，它位于网络层。</p>
</blockquote>
<h4 id="4-链路层：以太网协议"><a href="#4-链路层：以太网协议" class="headerlink" title="4. 链路层：以太网协议"></a>4. 链路层：以太网协议</h4><p><strong>以太网协议</strong></p>
<p>根据以太网协议将数据分为以 “帧” 为单位的数据包，每一帧分为两个部分：</p>
<ul>
<li>标头：数据包的发送者、接受者、数据类型</li>
<li>数据：数据包具体内容</li>
</ul>
<p><strong>Mac 地址</strong></p>
<p>以太网规定了连入网络的所有设备都必须具备 “网卡” 接口，数据包都是从一块网卡传递到另一块网卡，网卡的地址就是 Mac 地址。每一个 Mac 地址都是独一无二的，具备了一对一的能力。</p>
<p><strong>广播</strong></p>
<p>发送数据的方法很原始，直接把数据通过 ARP 协议，向本网络的所有机器发送，接收方根据标头信息与自身 Mac 地址比较，一致就接受，否则丢弃。</p>
<p>注意：接收方迴应是单播。</p>
<blockquote>
<p>相关知识点：</p>
<p>1.ARP 攻击</p>
</blockquote>
<p><strong>服务器接受请求</strong></p>
<p>接受过程就是把以上步骤逆转过来，参见上图。</p>
<h3 id="服务器处理请求"><a href="#服务器处理请求" class="headerlink" title="服务器处理请求"></a>服务器处理请求</h3><p>大致流程</p>
<p><img src="https://i.loli.net/2020/10/07/I78Dj69YHnh12Rx.png" alt="What_happens_when_you_type_an_URL_in_the_browser_and_press_enter_1.png"></p>
<p><strong>HTTPD</strong></p>
<p>最常见的 HTTPD 有 Linux 上常用的 Apache 和 Nginx，以及 Windows 上的 IIS。</p>
<p>它会监听得到的请求，然后开启一个子进程去处理这个请求。</p>
<p><strong>处理请求</strong></p>
<p>接受 TCP 报文后，会对连接进行处理，对 HTTP 协议进行解析（请求方法、域名、路径等），并且进行一些验证：</p>
<ul>
<li>验证是否配置虚拟主机</li>
<li>验证虚拟主机是否接受此方法</li>
<li>验证该用户可以使用该方法（根据 IP 地址、身份信息等）</li>
</ul>
<p><strong>重定向</strong></p>
<p>假如服务器配置了 HTTP 重定向，就会返回一个 301永久重定向响应，浏览器就会根据响应，重新发送 HTTP 请求（重新执行上面的过程）。</p>
<blockquote>
<p>关于更多：详见这篇文章</p>
</blockquote>
<p><strong>URL 重写</strong></p>
<p>然后会查看 URL 重写规则，如果请求的文件是真实存在的，比如图片、html、css、js 文件等，则会直接把这个文件返回。</p>
<p>否则服务器会按照规则把请求重写到 一个 REST 风格的 URL 上。</p>
<p>然后根据动态语言的脚本，来决定调用什么类型的动态文件解释器来处理这个请求。</p>
<p>以 PHP 语言的 MVC 框架举例，它首先会初始化一些环境的参数，根据 URL 由上到下地去匹配路由，然后让路由所定义的方法去处理请求。</p>
<h3 id="浏览器接受响应"><a href="#浏览器接受响应" class="headerlink" title="浏览器接受响应"></a>浏览器接受响应</h3><p>浏览器接收到来自服务器的响应资源后，会对资源进行分析。</p>
<p>首先查看 Response header，根据不同状态码做不同的事（比如上面提到的重定向）。</p>
<p>如果响应资源进行了压缩（比如 gzip），还需要进行解压。</p>
<p>然后，对响应资源做缓存。</p>
<p>接下来，根据响应资源里的 MIME 类型去解析响应内容（比如 HTML、Image 各有不同的解析方式）。</p>
<h3 id="渲染页面"><a href="#渲染页面" class="headerlink" title="渲染页面"></a>渲染页面</h3><p><strong>浏览器内核</strong></p>
<p><img src="https://i.loli.net/2020/10/07/CeRMYqWbhjZg3m7.png" alt="What_happens_when_you_type_an_URL_in_the_browser_and_press_enter_broswer.png"></p>
<p>不同的浏览器内核，渲染过程也不完全相同，但大致流程都差不多。</p>
<p><strong>基本流程</strong></p>
<p><img src="https://i.loli.net/2020/10/07/6C7sJ5xwEnacMYq.png" alt="What_happens_when_you_type_an_URL_in_the_browser_and_press_enter_2.png"></p>
<h4 id="HTML-解析"><a href="#HTML-解析" class="headerlink" title="HTML 解析"></a>HTML 解析</h4><p>首先要知道浏览器解析是从上往下一行一行地解析的。</p>
<p>解析的过程可以分为四个步骤：</p>
<p><strong>1.解码（encoding）</strong></p>
<p>传输回来的其实都是一些二进制字节数据，浏览器需要根据文件指定编码（例如 UTF-8）转换成字符串，也就是 HTML 代码。</p>
<p><strong>2.预解析（pre-parsing）</strong></p>
<p>预解析做的事情是提前加载资源，减少处理时间，它会识别一些会请求资源的属性，比如img标籤的src属性，并将这个请求加到请求队列中。</p>
<p><strong>3.符号化（Tokenization）</strong></p>
<p>符号化是词法分析的过程，将输入解析成符号，HTML 符号包括，开始标籤、结束标籤、属性名和属性值。</p>
<p>它通过一个状态机去识别符号的状态，比如遇到&lt;，&gt;状态都会产生变化。</p>
<p><strong>4.构建树（tree construction）</strong></p>
<blockquote>
<p>注意：符号化和构建树是并行操作的，也就是説只要解析到一个开始标籤，就会创建一个 DOM 节点。</p>
</blockquote>
<p>在上一步符号化中，解析器获得这些标记，然后以合适的方法创建DOM对象并把这些符号插入到DOM对象中。</p>
<figure class="highlight html"><table><tr><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">title</span>&gt;</span>Web page parsing<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">h1</span>&gt;</span>Web page parsing<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">p</span>&gt;</span>This is an example Web page.<span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>

<p><img src="https://i.loli.net/2020/10/07/Wsj2DGuqcNdoOwJ.png" alt="What_happens_when_you_type_an_URL_in_the_browser_and_press_enter_html.png"></p>
<p><strong>浏览器容错进制</strong></p>
<p>你从来没有在浏览器看过类似” 语法无效” 的错误，这是因为浏览器去纠正错误的语法，然后继续工作。</p>
<p><strong>事件</strong></p>
<p>当整个解析的过程完成以后，浏览器会通过DOMContentLoaded事件来通知DOM解析完成。</p>
<p><strong>CSS 解析</strong><br>一旦浏览器下载了 CSS，CSS 解析器就会处理它遇到的任何 CSS，根据语法规範解析出所有的 CSS 并进行标记化，然后我们得到一个规则表。</p>
<p><strong>CSS 匹配规则</strong></p>
<p>在匹配一个节点对应的 CSS 规则时，是按照从右到左的顺序的，例如：div p { font-size :14px }会先寻找所有的p标籤然后判断它的父元素是否为div。</p>
<p>所以我们写 CSS 时，儘量用 id 和 class，千万不要过度层叠。</p>
<p><strong>渲染树</strong><br>其实这就是一个 DOM 树和 CSS 规则树合併的过程。</p>
<p>注意：渲染树会忽略那些不需要渲染的节点，比如设置了display:none的节点。</p>
<p><strong>计算</strong></p>
<p>通过计算让任何尺寸值都减少到三个可能之一：auto、百分比、px，比如把rem转化为px。</p>
<p><strong>级联</strong></p>
<p>浏览器需要一种方法来确定哪些样式才真正需要应用到对应元素，所以它使用一个叫做specificity的公式，这个公式会通过：</p>
<ol>
<li>标籤名、class、id</li>
<li>是否内联样式</li>
<li>!important</li>
</ol>
<p>然后得出一个权重值，取最高的那个。</p>
<p><strong>渲染阻塞</strong></p>
<p>当遇到一个script标籤时，DOM 构建会被暂停，直至脚本完成执行，然后继续构建 DOM 树。</p>
<p>但如果 JS 依赖 CSS 样式，而它还没有被下载和构建时，浏览器就会延迟脚本执行，直至 CSS Rules 被构建。</p>
<p>所有我们知道：</p>
<ul>
<li>CSS 会阻塞 JS 执行</li>
<li>JS 会阻塞后面的 DOM 解析</li>
</ul>
<p>为了避免这种情况，应该以下原则：</p>
<p>CSS 资源排在 JavaScript 资源前面<br>JS 放在 HTML 最底部，也就是 </body>前<br>另外，如果要改变阻塞模式，可以使用 defer 与 async，详见：这篇文章</p>
<h5 id="佈局与绘製"><a href="#佈局与绘製" class="headerlink" title="佈局与绘製"></a>佈局与绘製</h5><p>确定渲染树种所有节点的几何属性，比如：位置、大小等等，最后输入一个盒子模型，它能精準地捕获到每个元素在屏幕内的準确位置与大小。</p>
<p>然后遍歷渲染树，调用渲染器的 paint() 方法在屏幕上显示其内容。</p>
<h5 id="合併渲染层"><a href="#合併渲染层" class="headerlink" title="合併渲染层"></a>合併渲染层</h5><p>把以上绘製的所有图片合併，最终输出一张图片。</p>
<h5 id="迴流与重绘"><a href="#迴流与重绘" class="headerlink" title="迴流与重绘"></a>迴流与重绘</h5><p><strong>迴流 (reflow)</strong></p>
<p>当浏览器发现某个部分发现变化影响了佈局时，需要倒回去重新渲染，会从html标籤开始递归往下，重新计算位置和大小。</p>
<p>reflow 基本是无法避免的，因为当你滑动一下鼠标、resize 窗口，页面就会产生变化。</p>
<p><strong>重绘 (repaint)</strong></p>
<p>改变了某个元素的背景色、文字颜色等等不会影响周围元素的位置变化时，就会发生重绘。</p>
<p>每次重绘后，浏览器还需要合併渲染层并输出到屏幕上。</p>
<p>迴流的成本要比重绘高很多，所以我们应该儘量避免产生迴流。</p>
<p>比如：</p>
<ul>
<li>display:none 会触发迴流，而 visibility:hidden 只会触发重绘。</li>
</ul>
<h5 id="JavaScript-编译执行"><a href="#JavaScript-编译执行" class="headerlink" title="JavaScript 编译执行"></a>JavaScript 编译执行</h5><p>大致流程</p>
<p><img src="https://i.loli.net/2020/10/07/aL12uPIoQvi45Cq.png" alt="What_happens_when_you_type_an_URL_in_the_browser_and_press_enter_3.png"></p>
<p>可以分为三个阶段：</p>
<h6 id="词法分析"><a href="#词法分析" class="headerlink" title="词法分析"></a>词法分析</h6><p>JS 脚本加载完毕后，会首先进入语法分析阶段，它首先会分析代码块的语法是否正确，不正确则抛出 “语法错误”，停止执行。</p>
<p>几个步骤：</p>
<ol>
<li>分词，例如将var a = 2，，分成var、a、=、2这样的词法单元。</li>
<li>解析，将词法单元转换成抽象语法树（AST）。</li>
<li>代码生成，将抽象语法树转换成机器指令。</li>
</ol>
<h6 id="预编译"><a href="#预编译" class="headerlink" title="预编译"></a>预编译</h6><p>JS 有三种运行环境：</p>
<ol>
<li>全局环境</li>
<li>函数环境</li>
<li>eval</li>
</ol>
<p>每进入一个不同的运行环境都会创建一个对应的执行上下文，根据不同的上下文环境，形成一个函数调用栈，栈底永远是全局执行上下文，栈顶则永远是当前执行上下文。</p>
<p><strong>创建执行上下文</strong></p>
<p>创建执行上下文的过程中，主要做了以下三件事：</p>
<ul>
<li>创建变量对象<ul>
<li>参数、函数、变量</li>
</ul>
</li>
<li>建立作用域链<ul>
<li>确认当前执行环境是否能访问变量</li>
</ul>
</li>
<li>确定 This 指向</li>
</ul>
<h6 id="执行"><a href="#执行" class="headerlink" title="执行"></a>执行</h6><p><strong>JS 线程</strong></p>
<p><img src="https://i.loli.net/2020/10/07/bd34kzGfuiYxv2t.png" alt="What_happens_when_you_type_an_URL_in_the_browser_and_press_enter_7.png"></p>
<p>虽然 JS 是单线程的，但实际上参与工作的线程一共有四个：</p>
<blockquote>
<p>其中三个只是协助，只有 JS 引擎线程是真正执行的</p>
</blockquote>
<ul>
<li>JS 引擎线程：也叫 JS 内核，负责解析执行 JS 脚本程序的主线程，例如 V8 引擎</li>
<li>事件触发线程：属于浏览器内核线程，主要用于控制事件，例如鼠标、键盘等，当事件被触发时，就会把事件的处理函数推进事件队列，等待 JS 引擎线程执行</li>
<li>定时器触发线程：主要控制setInterval和setTimeout，用来计时，计时完毕后，则把定时器的处理函数推进事件队列中，等待 JS 引擎线程。</li>
<li>HTTP 异步请求线程：通过 XMLHttpRequest 连接后，通过浏览器新开的一个线程，监控 readyState 状态变更时，如果设置了该状态的回调函数，则将该状态的处理函数推进事件队列中，等待 JS 引擎线程执</li>
</ul>
<p><strong>注：浏览器对同一域名的併发连接数是有限的，通常为 6 个。</strong></p>
<p><strong>宏任务</strong></p>
<p>分为：</p>
<ul>
<li>同步任务：按照顺序执行，只有前一个任务完成后，才能执行后一个任务</li>
<li>异步任务：不直接执行，只有满足触发条件时，相关的线程将该异步任务推进任务队列中，等待 JS 引擎主线程上的任务执行完毕时才开始执行，例如异步 Ajax、DOM 事件，setTimeout 等。</li>
</ul>
<p><strong>微任务</strong></p>
<p>微任务是 ES6 和 Node 环境下的，主要 API 有：Promise，process.nextTick。</p>
<p>微任务的执行在宏任务的同步任务之后，在异步任务之前。</p>
<p><img src="https://i.loli.net/2020/10/07/bd34kzGfuiYxv2t.png" alt="What_happens_when_you_type_an_URL_in_the_browser_and_press_enter_7.png"></p>
<p>代码例子</p>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="built_in">console</span>.log(<span class="string">&#x27;1&#x27;</span>); <span class="comment">// 宏任务 同步</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">setTimeout</span>(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;2&#x27;</span>); <span class="comment">// 宏任务 异步</span></span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="keyword">new</span> <span class="built_in">Promise</span>(<span class="function"><span class="keyword">function</span>(<span class="params">resolve</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;3&#x27;</span>); <span class="comment">// 宏任务 同步</span></span><br><span class="line">    resolve();</span><br><span class="line">&#125;).then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">&#x27;4&#x27;</span>) <span class="comment">// 微任务</span></span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">&#x27;5&#x27;</span>) <span class="comment">// 宏任务 同步</span></span><br></pre></td></tr></table></figure>

<p>以上代码输出顺序为：1,3,5,4,2</p>
<p><strong>参考文档:</strong></p>
<ul>
<li><p>[what-happens-when-zh]: <a target="_blank" rel="noopener" href="https://github.com/skyline75489/what-happens-when-zh_CN">https://github.com/skyline75489/what-happens-when-zh_CN</a></p>
</li>
<li><p>[Tags TO DOM]: <a target="_blank" rel="noopener" href="https://alistapart.com/article/tags-to-dom/">https://alistapart.com/article/tags-to-dom/</a></p>
</li>
<li><p>[彻底理解浏览器的缓存机制]: <a target="_blank" rel="noopener" href="https://heyingye.github.io/2018/04/16/%E5%BD%BB%E5%BA%95%E7%90%86%E8%A7%A3%E6%B5%8F%E8%A7%88%E5%99%A8%E7%9A%84%E7%BC%93%E5%AD%98%E6%9C%BA%E5%88%B6/">https://heyingye.github.io/2018/04/16/%E5%BD%BB%E5%BA%95%E7%90%86%E8%A7%A3%E6%B5%8F%E8%A7%88%E5%99%A8%E7%9A%84%E7%BC%93%E5%AD%98%E6%9C%BA%E5%88%B6/</a></p>
</li>
<li><p>[浏览器的工作原理：新式网络浏览器幕后揭祕]: <a target="_blank" rel="noopener" href="https://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/#The_rendering_engine">https://www.html5rocks.com/zh/tutorials/internals/howbrowserswork/#The_rendering_engine</a></p>
</li>
<li><p>[深入浅出浏览器渲染原理]: <a target="_blank" rel="noopener" href="https://blog.fundebug.com/2019/01/03/understand-browser-rendering/">https://blog.fundebug.com/2019/01/03/understand-browser-rendering/</a></p>
</li>
<li><p>[js引擎的执行过程(一)]: <a target="_blank" rel="noopener" href="https://heyingye.github.io/2018/03/19/js%E5%BC%95%E6%93%8E%E7%9A%84%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%88%E4%B8%80%EF%BC%89/#%E9%A2%84%E7%BC%96%E8%AF%91%E9%98%B6%E6%AE%B5">https://heyingye.github.io/2018/03/19/js%E5%BC%95%E6%93%8E%E7%9A%84%E6%89%A7%E8%A1%8C%E8%BF%87%E7%A8%8B%EF%BC%88%E4%B8%80%EF%BC%89/#%E9%A2%84%E7%BC%96%E8%AF%91%E9%98%B6%E6%AE%B5</a></p>
</li>
</ul>
</div><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="mailto:undefined">Leon</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="https://gitee.com/Rickest_Rick/rickest_rick.git/2020/10/07/URL/">https://gitee.com/Rickest_Rick/rickest_rick.git/2020/10/07/URL/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="https://gitee.com/Rickest_Rick/rickest_rick.git" target="_blank">Leonの博客</a>！</span></div></div><div class="tag_share"><div class="post-meta__tag-list"><a class="post-meta__tags" href="/rickest_rick/tags/http%E7%BD%91%E7%BB%9C/">http网络</a></div><div class="post_share"><div class="social-share" data-image="https://pic.downk.cc/item/5ff721fa3ffa7d37b379bbff.jpg" data-sites="facebook,twitter,wechat,weibo,qq"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/social-share.js/dist/css/share.min.css"><script src="https://cdn.jsdelivr.net/npm/social-share.js/dist/js/social-share.min.js" defer></script></div></div><div class="post-reward"><div class="reward-button"><i class="fas fa-qrcode"></i> 打赏<div class="reward-main"><ul class="reward-all"><li class="reward-item"><a href="/img/wechat.jpg" target="_blank"><img class="post-qr-code-img" src="/rickest_rick/img/wechat.jpg" alt="wechat"/></a><div class="post-qr-code-desc">wechat</div></li><li class="reward-item"><a href="/img/alipay.jpg" target="_blank"><img class="post-qr-code-img" src="/rickest_rick/img/alipay.jpg" alt="alipay"/></a><div class="post-qr-code-desc">alipay</div></li></ul></div></div></div><nav class="pagination-post" id="pagination"><div class="next-post pull-full"><a href="/rickest_rick/2020/10/03/My-new-post/"><img class="next-cover" src="https://pic.downk.cc/item/5ff71e863ffa7d37b3776db6.jpg" onerror="onerror=null;src='/rickest_rick/img/404.jpg'"><div class="pagination-info"><div class="label">下一篇</div><div class="next_info">My new post</div></div></a></div></nav></article></main><footer id="footer"><div id="footer-wrap"><div class="copyright">&copy;undefined - 2021  <i id="heartbeat" class="fa fas fa-heartbeat"></i> Leon</div><div class="framework-info"><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly</a></div><div class="footer_custom_text">Hi, welcome to my blog</div></div><head><link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/HCLonely/images@master/others/heartbeat.min.css"></head?>       </footer></div><section id="rightside"><div id="rightside-config-hide"><button id="readmode" type="button" title="阅读模式"><i class="fas fa-book-open"></i></button><button id="translateLink" type="button" title="简繁转换">简</button><button id="darkmode" type="button" title="浅色和深色模式转换"><i class="fas fa-adjust"></i></button></div><div id="rightside-config-show"><button id="rightside_config" type="button" title="设置"><i class="fas fa-cog"></i></button><button class="close" id="mobile-toc-button" type="button" title="目录"><i class="fas fa-list-ul"></i></button><button id="chat_btn" type="button" title="rightside.chat_btn"><i class="fas fa-sms"></i></button><button id="go-up" type="button" title="回到顶部"><i class="fas fa-arrow-up"></i></button></div></section><div class="search-dialog" id="local-search"><div class="search-dialog__title" id="local-search-title">本地搜索</div><div id="local-input-panel"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章" type="text"/></div></div></div><hr/><div id="local-search-results"><div id="local-hits"></div><div id="local-stats"><div class="local-search-stats__hr" id="hr"><span>由</span> <a target="_blank" rel="noopener" href="https://github.com/wzpan/hexo-generator-search" style="color:#49B1F5;">hexo-generator-search</a>
 <span>提供支持</span></div></div></div><span class="search-close-button"><i class="fas fa-times"></i></span></div><div id="search-mask"></div><div><script src="https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js"></script><script src="/rickest_rick/js/utils.js"></script><script src="/rickest_rick/js/main.js"></script><script src="/rickest_rick/js/tw_cn.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar/dist/snackbar.min.js"></script><script src="/rickest_rick/js/search/local-search.js"></script><script>var preloader = {
  endLoading: () => {
    document.body.style.overflow = 'auto';
    document.getElementById('loading-box').classList.add("loaded")
  },
  initLoading: () => {
    document.body.style.overflow = '';
    document.getElementById('loading-box').classList.remove("loaded")

  }
}
window.addEventListener('load',()=> {preloader.endLoading()})</script><div class="js-pjax"><script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script></div><canvas class="fireworks" mobile="true"></canvas><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/fireworks.min.js"></script><script defer="defer" id="ribbon" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/canvas-ribbon.min.js" size="150" alpha="0.6" zIndex="-1" mobile="true" data-click="true"></script><script id="canvas_nest" defer="defer" color="0,0,255" opacity="0.7" zIndex="-1" count="120" mobile="true" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/canvas-nest.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/dist/activate-power-mode.min.js"></script><script>POWERMODE.colorful = true;
POWERMODE.shake = true;
POWERMODE.mobile = true;
document.body.addEventListener('input', POWERMODE);
</script><script src="https://cdn.jsdelivr.net/npm/pjax/pjax.min.js"></script><script>let pjaxSelectors = [
  'title',
  '#config_change',
  '#body-wrap',
  '#rightside-config-hide',
  '#rightside-config-show',
  '.js-pjax'
]

if (false) {
  pjaxSelectors.unshift('meta[property="og:image"]', 'meta[property="og:title"]', 'meta[property="og:url"]')
}

var pjax = new Pjax({
  elements: 'a:not([target="_blank"])',
  selectors: pjaxSelectors,
  cacheBust: false,
  analytics: false,
  scrollRestoration: false
})

document.addEventListener('pjax:complete', function () {
  window.refreshFn()

  $('script[data-pjax]').each(function () {
    $(this).parent().append($(this).remove())
  })

  GLOBAL_CONFIG.islazyload && window.lazyLoadInstance.update()

  typeof chatBtnFn === 'function' && chatBtnFn()
  typeof panguInit === 'function' && panguInit()

  if (typeof gtag === 'function') {
    gtag('config', '', {'page_path': window.location.pathname});
  }

  typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()

  // Analytics
  if (false) {
    MtaH5.pgv()
  }

  // prismjs
  typeof Prism === 'object' && Prism.highlightAll()

  typeof preloader === 'object' && preloader.endLoading()
})


document.addEventListener('pjax:send', function () {
  typeof preloader === 'object' && preloader.initLoading()
  
  if (window.aplayers) {
    for (let i = 0; i < window.aplayers.length; i++) {
      if (!window.aplayers[i].options.fixed) {
        window.aplayers[i].destroy()
      }
    }
  }

  typeof typed === 'object' && typed.destroy()

  $(window).off('scroll')

  //reset readmode
  $('body').hasClass('read-mode') && $('body').removeClass('read-mode')

})</script></div><script src="/rickest_rick/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"pluginRootPath":"live2dw/","pluginJsPath":"lib/","pluginModelPath":"assets/","tagMode":false,"log":false,"model":{"jsonPath":"/rickest_rick/live2dw/assets/assets/haru02.model.json"},"display":{"position":"right","width":200,"height":350,"hOffset":10,"vOffset":0},"mobile":{"show":true,"scale":0.5},"react":{"opacityDefault":0.7,"opacityOnHover":1}});</script></body></html>